//-----------------------------------------------------------------------------
//  Copyright (c) 2013 by HangZhou HenqgQiao Design Corporation. All rights reserved.
//
//  Project  : 
//  Module   : over sample the input data with 8-phases 311M clock
//  Parent   : 
//  Children : 
//
//  Description: 
//
//  Parameters:
//  Local Parameters:
//
//  Notes       : 
//
//  Multicycle and False Paths

module SOH4_RB2(
   input                         SOH4_RESET,
   input                         SOH4_RCLK,

   input[1:0]                    RB2_IN_FMCNT4,
   input[8:0]                    RB2_IN_FMCNT270,
   input[3:0]                    RB2_IN_FMCNT9,
   input[7:0]                    RB2_IN_DATA,
   input                         RB2_IN_DEN,

   output reg[6:0]               RB2_OUT_ERRCNT,
   output reg                    RB2_OUT_ERREN
   );


wire[1:0]                        B2_FMCNT4;
wire[8:0]                        B2_FMCNT270;
wire[3:0]                        B2_FMCNT9;
reg[1:0]                         B2_FMCNT3;
wire[7:0]                        B2_DATA;
wire                             B2_DEN;
reg[3:0]                         B2_ADDR;
reg                              B2_EN;
reg[7:0]                         B2_RD_CALCULATING, B2_WR_CALCULATING;
reg[7:0]                         B2_RD_RESULT, B2_WR_RESULT;
reg[95:0]                        B2_CALCULATING_REGS;
reg[95:0]                        B2_RESULT_REGS;

wire[7:0]                        B2_OUT_ERROR_VECTOR;
wire                             B2_OUT_ERROR_EN;
wire                             B2_OUT_FP;

reg[7:0]                         B2CNT_ERROR_VECTOR;
reg                              B2CNT_ERROR_EN;
reg                              B2CNT_FP;
reg[6:0]                         B2CNT_ERROR_CNT;
reg[7:0]                         B2CNT_ERREN_CNT;




  assign B2_FMCNT4[1:0]        = RB2_IN_FMCNT4[1:0];
  assign B2_FMCNT270[8:0]      = RB2_IN_FMCNT270[8:0];
  assign B2_FMCNT9[3:0]        = RB2_IN_FMCNT9[3:0];
  assign B2_DATA[7:0]          = RB2_IN_DATA[7:0];
  assign B2_DEN                = RB2_IN_DEN;


always @( B2_FMCNT270 or B2_FMCNT9 ) begin
   if ( (B2_FMCNT9[3:0]==4'd0 || B2_FMCNT9[3:0]==4'd1 || B2_FMCNT9[3:0]==4'd2 ) && B2_FMCNT270[8:0]<9'd9 )
      B2_EN                                              <= 1'b0;
   else
      B2_EN                                              <= 1'b1;
end


always @( B2_FMCNT4 ) begin
      B2_ADDR[1:0]                                       <= B2_FMCNT4[1:0];
end
always @( posedge SOH4_RESET or posedge SOH4_RCLK ) begin
   if ( SOH4_RESET==1'b1 )
      B2_ADDR[3:2]                                       <= 2'd0;
   else begin
      if ( B2_FMCNT9[3:0]==4'd8 && B2_FMCNT270[8:0]==9'd269 && B2_FMCNT4[1:0]==2'd3 && B2_DEN==1'b1 )
            B2_ADDR[3:2]                                 <= 2'd0;
      else if ( B2_FMCNT4[1:0]==2'd3 && B2_DEN==1'b1 ) begin
         if ( B2_ADDR[3:2]==2'd2 )
            B2_ADDR[3:2]                                 <= 2'd0;
         else
            B2_ADDR[3:2]                                 <= B2_ADDR[3:2] +2'd1;
      end
   end
end


always @( B2_CALCULATING_REGS or B2_ADDR  ) begin
   case ( B2_ADDR[3:0] )
   4'b0000 :  B2_RD_CALCULATING[7:0]                     <= B2_CALCULATING_REGS[7:0];
   4'b0001 :  B2_RD_CALCULATING[7:0]                     <= B2_CALCULATING_REGS[15:8];
   4'b0010 :  B2_RD_CALCULATING[7:0]                     <= B2_CALCULATING_REGS[23:16];
   4'b0011 :  B2_RD_CALCULATING[7:0]                     <= B2_CALCULATING_REGS[31:24];
   4'b0100 :  B2_RD_CALCULATING[7:0]                     <= B2_CALCULATING_REGS[39:32];
   4'b0101 :  B2_RD_CALCULATING[7:0]                     <= B2_CALCULATING_REGS[47:40];
   4'b0110 :  B2_RD_CALCULATING[7:0]                     <= B2_CALCULATING_REGS[55:48];
   4'b0111 :  B2_RD_CALCULATING[7:0]                     <= B2_CALCULATING_REGS[63:56];
   4'b1000 :  B2_RD_CALCULATING[7:0]                     <= B2_CALCULATING_REGS[71:64];
   4'b1001 :  B2_RD_CALCULATING[7:0]                     <= B2_CALCULATING_REGS[79:72];
   4'b1010 :  B2_RD_CALCULATING[7:0]                     <= B2_CALCULATING_REGS[87:80];
   4'b1011 :  B2_RD_CALCULATING[7:0]                     <= B2_CALCULATING_REGS[95:88];
   default :  B2_RD_CALCULATING[7:0]                     <= 8'd0;
   endcase
end

always @( posedge SOH4_RESET or posedge SOH4_RCLK ) begin
   if ( SOH4_RESET==1'b1 )
      B2_CALCULATING_REGS[95:0]                          <= 96'd0;
   else if ( B2_EN==1'b1 && B2_DEN==1'b1 ) begin
      case ( B2_ADDR[3:0] )
      4'b0000 :  B2_CALCULATING_REGS[7:0]                <= B2_WR_CALCULATING[7:0];
      4'b0001 :  B2_CALCULATING_REGS[15:8]               <= B2_WR_CALCULATING[7:0];
      4'b0010 :  B2_CALCULATING_REGS[23:16]              <= B2_WR_CALCULATING[7:0];
      4'b0011 :  B2_CALCULATING_REGS[31:24]              <= B2_WR_CALCULATING[7:0];
      4'b0100 :  B2_CALCULATING_REGS[39:32]              <= B2_WR_CALCULATING[7:0];
      4'b0101 :  B2_CALCULATING_REGS[47:40]              <= B2_WR_CALCULATING[7:0];
      4'b0110 :  B2_CALCULATING_REGS[55:48]              <= B2_WR_CALCULATING[7:0];
      4'b0111 :  B2_CALCULATING_REGS[63:56]              <= B2_WR_CALCULATING[7:0];
      4'b1000 :  B2_CALCULATING_REGS[71:64]              <= B2_WR_CALCULATING[7:0];
      4'b1001 :  B2_CALCULATING_REGS[79:72]              <= B2_WR_CALCULATING[7:0];
      4'b1010 :  B2_CALCULATING_REGS[87:80]              <= B2_WR_CALCULATING[7:0];
      4'b1011 :  B2_CALCULATING_REGS[95:88]              <= B2_WR_CALCULATING[7:0];
      default :  ;
      endcase
   end
end
always @( B2_RD_CALCULATING or B2_FMCNT270 or B2_FMCNT9 or B2_DATA) begin
   if ( (B2_FMCNT270[8:0]==9'd269 || B2_FMCNT270[8:0]==9'd268 || B2_FMCNT270[8:0]==9'd267) && B2_FMCNT9[3:0]==4'd8 )
      B2_WR_CALCULATING[7:0]                             <= 8'd0;
   else
      B2_WR_CALCULATING[7:0]                             <= B2_RD_CALCULATING[7:0] ^ B2_DATA[7:0];
end



always @( B2_RESULT_REGS or B2_ADDR  ) begin
   case ( B2_ADDR[3:0] )
   4'b0000 :  B2_RD_RESULT[7:0]                          <= B2_RESULT_REGS[7:0];
   4'b0001 :  B2_RD_RESULT[7:0]                          <= B2_RESULT_REGS[15:8];
   4'b0010 :  B2_RD_RESULT[7:0]                          <= B2_RESULT_REGS[23:16];
   4'b0011 :  B2_RD_RESULT[7:0]                          <= B2_RESULT_REGS[31:24];
   4'b0100 :  B2_RD_RESULT[7:0]                          <= B2_RESULT_REGS[39:32];
   4'b0101 :  B2_RD_RESULT[7:0]                          <= B2_RESULT_REGS[47:40];
   4'b0110 :  B2_RD_RESULT[7:0]                          <= B2_RESULT_REGS[55:48];
   4'b0111 :  B2_RD_RESULT[7:0]                          <= B2_RESULT_REGS[63:56];
   4'b1000 :  B2_RD_RESULT[7:0]                          <= B2_RESULT_REGS[71:64];
   4'b1001 :  B2_RD_RESULT[7:0]                          <= B2_RESULT_REGS[79:72];
   4'b1010 :  B2_RD_RESULT[7:0]                          <= B2_RESULT_REGS[87:80];
   4'b1011 :  B2_RD_RESULT[7:0]                          <= B2_RESULT_REGS[95:88];
   default :  B2_RD_RESULT[7:0]                          <= 8'd0;
   endcase
end
always @( posedge SOH4_RESET or posedge SOH4_RCLK ) begin
   if ( SOH4_RESET==1'b1 )
      B2_RESULT_REGS[95:0]                               <= 96'd0;
   else if ( (B2_FMCNT270[8:0]==9'd269 || B2_FMCNT270[8:0]==9'd268 || B2_FMCNT270[8:0]==9'd267) && B2_FMCNT9[3:0]==4'd8 ) begin
      case ( B2_ADDR[3:0] )
      4'b0000 :  B2_RESULT_REGS[7:0]                     <= B2_WR_RESULT[7:0];
      4'b0001 :  B2_RESULT_REGS[15:8]                    <= B2_WR_RESULT[7:0];
      4'b0010 :  B2_RESULT_REGS[23:16]                   <= B2_WR_RESULT[7:0];
      4'b0011 :  B2_RESULT_REGS[31:24]                   <= B2_WR_RESULT[7:0];
      4'b0100 :  B2_RESULT_REGS[39:32]                   <= B2_WR_RESULT[7:0];
      4'b0101 :  B2_RESULT_REGS[47:40]                   <= B2_WR_RESULT[7:0];
      4'b0110 :  B2_RESULT_REGS[55:48]                   <= B2_WR_RESULT[7:0];
      4'b0111 :  B2_RESULT_REGS[63:56]                   <= B2_WR_RESULT[7:0];
      4'b1000 :  B2_RESULT_REGS[71:64]                   <= B2_WR_RESULT[7:0];
      4'b1001 :  B2_RESULT_REGS[79:72]                   <= B2_WR_RESULT[7:0];
      4'b1010 :  B2_RESULT_REGS[87:80]                   <= B2_WR_RESULT[7:0];
      4'b1011 :  B2_RESULT_REGS[95:88]                   <= B2_WR_RESULT[7:0];
      default :  ;
      endcase
   end
end
always @( B2_RD_CALCULATING or B2_DATA ) begin
      B2_WR_RESULT[7:0]                                  <= B2_RD_CALCULATING[7:0] ^ B2_DATA[7:0];
end

  assign B2_OUT_ERROR_VECTOR[7:0]     = B2_RD_RESULT[7:0] ^ B2_DATA[7:0];
  assign B2_OUT_ERROR_EN              = (B2_FMCNT9[3:0]==4'd4 && (B2_FMCNT270[8:0]==9'd0 || B2_FMCNT270[8:0]==9'd1 || B2_FMCNT270[8:0]==9'd2));
  assign B2_OUT_FP                    = B2_FMCNT9[3:0]==4'd0 && B2_FMCNT270[8:0]==9'd0 && B2_FMCNT4[1:0]==2'd0 && B2_DEN==2'd0;



always @( posedge SOH4_RESET or posedge SOH4_RCLK ) begin
   if ( SOH4_RESET==1'b1 ) begin
      B2CNT_ERROR_VECTOR[7:0]                           <= 8'd0;
      B2CNT_ERROR_EN                                    <= 1'd0;
      B2CNT_FP                                          <= 1'd0;
   end
   else begin
      B2CNT_ERROR_VECTOR[7:0]                           <= B2_OUT_ERROR_VECTOR[7:0];
      B2CNT_ERROR_EN                                    <= B2_OUT_ERROR_EN;
      B2CNT_FP                                          <= B2_OUT_FP;
   end
end
always @( posedge SOH4_RESET or posedge SOH4_RCLK ) begin
   if ( SOH4_RESET==1'b1 )
      B2CNT_ERROR_CNT[6:0]                              <= 7'd0;
   else begin
      if ( B2CNT_FP==1'b1 )
         B2CNT_ERROR_CNT[6:0]                           <= 7'd0;
      else if (  B2CNT_ERROR_EN==1'b1 )
         B2CNT_ERROR_CNT[6:0]                           <= B2CNT_ERROR_CNT[6:0] + {6'd0, B2CNT_ERROR_VECTOR[7]} + {6'd0, B2CNT_ERROR_VECTOR[6]} + {6'd0, B2CNT_ERROR_VECTOR[5]} + {6'd0, B2CNT_ERROR_VECTOR[4]} +
                                                                                  {6'd0, B2CNT_ERROR_VECTOR[3]} + {6'd0, B2CNT_ERROR_VECTOR[2]} + {6'd0, B2CNT_ERROR_VECTOR[1]} + {6'd0, B2CNT_ERROR_VECTOR[0]};
   end
end


always @( posedge SOH4_RESET or posedge SOH4_RCLK ) begin
   if ( SOH4_RESET==1'b1 )
      RB2_OUT_ERRCNT[6:0]                               <= 7'd0;
   else if ( B2CNT_FP==1'b1 )
      RB2_OUT_ERRCNT[6:0]                               <= B2CNT_ERROR_CNT[6:0];
end

always @( posedge SOH4_RESET or posedge SOH4_RCLK ) begin
   if ( SOH4_RESET==1'b1 )
      B2CNT_ERREN_CNT[7:0]                              <= 8'd0;
   else begin
      if ( B2CNT_FP==1'b1 )
         B2CNT_ERREN_CNT[7:0]                           <= 8'd128;
      else if ( B2CNT_ERREN_CNT[7:0]!=8'd0 ) begin
         B2CNT_ERREN_CNT[7:0]                           <= B2CNT_ERREN_CNT[7:0] +8'd0;
      end
   end
end
always @( posedge SOH4_RESET or posedge SOH4_RCLK ) begin
   if ( SOH4_RESET==1'b1 )
      RB2_OUT_ERREN                                     <= 1'b0;
   else begin
      if ( B2CNT_FP==1'b1 )
         RB2_OUT_ERREN                                  <= 1'b1;
      else if ( B2CNT_ERREN_CNT[7:0]!=8'd255 )
         RB2_OUT_ERREN                                  <= 1'b0;
   end
end


endmodule


